#include <iostream>
using namespace std;

// 英雄类
class Hero{
    protected:
        string name;    // 名字
        int life;       // 生命值
    public:
        Hero(){}
        Hero(string n, int l):name(n), life(l){}
        ~Hero(){}
        virtual void reduce_life(){
            life -= 0;
            cout << "英雄类减少生命值:-0 " << "剩余生命值:" << life << endl;
        }
};

// 法师类
class Master:public Hero{
    private:
        string skill;   // 技能
    public:
        Master(){}
        Master(string n, int l, string s):Hero(n, l), skill(s){}
        ~Master(){}
        void reduce_life(){
            life -= 100;
            cout << "法师类减少生命值:-100 " << "剩余生命值:" << life << endl;
        }
};

// 射手类
class Shooter:public Hero{
    private:
        int attack; // 攻击力
    public:
        Shooter(){}
        Shooter(string n, int l, int a):Hero(n, l), attack(a){}
        ~Shooter(){}
        void reduce_life(){
            life -= 200;
            cout << "射手类减少生命值:-200 " << "剩余生命值:" << life << endl;
        }
};
// 假如 Hero类有20个不同的子类  其他18个子类省略 ..


// 打野怪(每个英雄都可能有打野怪的动作)

// 第一版：C语言的写法(没有重载)
// void fight_wild_master(Master &x){
//     x.reduce_life();
// }
// void fight_wild_shooter(Shooter &x){
//     x.reduce_life();
// }
// 这种写法 我们需要定义 20个 不同名字的函数


// 第二版：C++的写法(函数重载)
// void fight_wild(Master &x){
//     x.reduce_life();
// }
// void fight_wild(Shooter &x){
//     x.reduce_life();
// }
// 这种写法 虽然函数名统一了 但是我们仍然需要定义 20个 不同形参版本的函数


// 第三版：C++的写法(多态)
void fight_wild(Hero &x){
    x.reduce_life();
}
// 这种写法 只写这一个函数即可
// 具体调用的是哪个类的 reduce_life 函数 取决于实参是哪个类的对象 

int main(int argc, const char *argv[]){
    // 第一版写法的函数调用
    // Master m1("妲己", 2000, "爱心攻击");
    // fight_wild_master(m1); // 函数不同名 不同的类对象需要调用不同名字的函数
    // Shooter s1("鲁班七号", 1500, 300);
    // fight_wild_shooter(s1);

    // 第二版写法的函数调用
    // Master m1("妲己", 2000, "爱心攻击");
    // fight_wild(m1); // 函数同名 调用相对简单
    // Shooter s1("鲁班七号", 1500, 300);
    // fight_wild(s1);

    // 第三版写法的函数调用
    Master m1("妲己", 2000, "爱心攻击");
    fight_wild(m1); // 函数同名 调用相对简单
    Shooter s1("鲁班七号", 1500, 300);
    fight_wild(s1);

    return 0;
}